package msg

import (
	"bytes"
	"encoding/binary"
	"errors"
)

// InnerCmd 内部服务器消息
type InnerCmd struct {
	GatewayServerId int32
	SessionUId      string
	UserId          int64
	MsgData         []byte
}

// ToByteArray 内部服务器消息转成字节数组
func (this *InnerCmd) ToByteArray() ([]byte, error) {
	// 将 sessionUId 转成字节数组
	sessionUIdByteArray := []byte(this.SessionUId)

	valArray := [...]interface{}{
		this.GatewayServerId,
		int32(len(sessionUIdByteArray)),
		sessionUIdByteArray,
		this.UserId,
		this.MsgData,
	}

	// 创建缓冲区对象
	buff := bytes.NewBuffer([]byte{})

	for _, val := range valArray {
		if err := binary.Write(buff, binary.BigEndian, val); nil != err {
			return nil, err
		}
	}

	return buff.Bytes(), nil
}

// FromByteArray 将字节数组转成内部服务器消息
func (this *InnerCmd) FromByteArray(byteArray []byte) error {
	if nil == byteArray ||
		len(byteArray) <= 0 {
		return errors.New("字节数组为空")
	}

	buff := bytes.NewBuffer(byteArray)

	if err := binary.Read(
		buff, binary.BigEndian, &this.GatewayServerId); nil != err {
		return err
	}

	// sessionUId 字节数量
	var sessionUIdByteCount int32 = 0

	if err := binary.Read(
		buff, binary.BigEndian, &sessionUIdByteCount); nil != err {
		return err
	}

	if sessionUIdByteCount > 0 {
		// 读取 sessionUId 字节数组
		sessionUIdByteArray := make([]byte, sessionUIdByteCount)

		if err := binary.Read(
			buff, binary.BigEndian, sessionUIdByteArray); nil != err {
			return err
		}

		this.SessionUId = string(sessionUIdByteArray)
	}

	if err := binary.Read(
		buff, binary.BigEndian, &this.UserId); nil != err {
		return err
	}

	// 读取全部剩余的字节
	this.MsgData = buff.Bytes()
	return nil
}
